from sqlalchemy import delete, select, desc, func
from sqlalchemy.ext.asyncio import AsyncSession

from module_stock.entity.do.stat_stock_do import StatStock
from module_stock.entity.vo.stat_stock_vo import StatStockModel, StatStockPageQueryModel
from utils.page_util import PageUtil


class StatStockDao:
    """
    股票统计模块数据库操作层
    """

    @classmethod
    async def get_stat_stock_list(cls, db: AsyncSession, query_object: StatStockPageQueryModel, is_page: bool = False):
        """
        根据查询参数获取股票统计列表信息

        :param db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 股票统计列表信息对象
        """
        query = (
            select(StatStock)
            .where(
                StatStock.stock_code.like(f'%{query_object.stock_code}%') if query_object.stock_code else True,
                StatStock.account_tag == query_object.account_tag if query_object.account_tag else True,
                StatStock.total_buy_quantity + StatStock.total_sell_quantity == 0 if query_object.zero else True,
            )
            .order_by(desc(StatStock.profit))
            .distinct()
        )
        stat_stock_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)

        return stat_stock_list

    @classmethod
    async def add_stat_stock_dao(cls, db: AsyncSession, stat_stock: StatStockModel):
        """
        新增股票统计数据库操作

        :param db: orm对象
        :param stat_stock: 股票统计对象
        :return:
        """
        db_stat_stock = StatStock(**stat_stock.model_dump(exclude={}))
        db.add(db_stat_stock)
        await db.flush()

        return db_stat_stock

    @classmethod
    async def clear_stat_stock_dao(cls, db: AsyncSession):
        """
        清空股票统计数据库操作

        :param db: orm对象
        :return:
        """
        await db.execute(delete(StatStock))

    @classmethod
    async def get_cleared_stock_amount_by_account_tags(cls, db: AsyncSession, account_tags: list):
        """
        根据账户标签列表获取清仓股票的资金总和

        :param db: orm对象
        :param account_tags: 账户标签列表
        :return: 清仓股票的资金总和
        """
        if not account_tags:
            return 0

        result = await db.execute(
            select(func.sum(StatStock.profit))
            .where(
                StatStock.account_tag.in_(account_tags),
                StatStock.total_buy_quantity + StatStock.total_sell_quantity == 0  # 清仓条件
            )
        )
        amount = result.scalar()
        return amount if amount else 0
